﻿using NLog;
using Scpi.GWInstek.Controler;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace TestGWApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public static Logger logger = LogManager.GetCurrentClassLogger();
        public event PropertyChangedEventHandler PropertyChanged;

        private GwPWSControler gwControler = null;
        private CancellationTokenSource cancellation = null;

        public int PowerOnCnt { get => _powerOnCnt;
            set
            {
                _powerOnCnt = value;
                if(PropertyChanged!=null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("PowerOnCnt"));
                }
            } 
        }
        private int _powerOnCnt = 0;

        private int _outputsecond;

        public int OutputSecond
        {
            get { return _outputsecond; }
            set 
            { _outputsecond = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("OutputSecond"));
                }
            }
        }

        private int _testCount;

        public int TestCount
        {
            get { return _testCount; }
            set { _testCount = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("TestCount"));
                }
            }
        }

        private int _runCount;

        public int RunCount
        {
            get { return _runCount; }
            set
            {
                _runCount = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("RunCount"));
                }
            }
        }

        private int _delaySecond;

        public int DelaySecond
        {
            get { return _delaySecond; }
            set { _delaySecond = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("DelaySecond"));
                }
            }
        }


        public MainWindow()
        {
            InitializeComponent();
            buttonPowerOff.IsEnabled = false;
            DataContext = this;
        }

        private async void Button_ClickAsync(object sender, RoutedEventArgs e)
        {
            string ipaddrstr = textBoxIpAddr.Text;

            gwControler = ControlerBuilder.BuildGwPWSCtr(ipaddrstr, ipaddrstr);

            var Result=await gwControler.ConnectRemoteAsync();
            if(!Result)
            {
                logger.Warn($"链接远端（{ipaddrstr}）失败");
            }
            else
            {
                logger.Info($"链接远端（{ipaddrstr}）成功");
            }
        }

        private void buttonDisconn_Click(object sender, RoutedEventArgs e)
        {
            gwControler?.Dispose();
        }

        private async void buttonPowerOn_Click(object sender, RoutedEventArgs e)
        {
            await OutputCtrl();
        }

        private async Task OutputCtrl()
        {
            var result = await gwControler.EnablePowerOutAsync();
            if (result == true)
            {
                await Dispatcher.BeginInvoke(new Action(() =>
                {
                    buttonPowerOn.IsEnabled = false;
                    buttonPowerOff.IsEnabled = true;
                }));
                PowerOnCnt++;
                logger.Info($"{gwControler.DeviceInfo.Name} PowerOn Ok! Cnt={PowerOnCnt}");
            }
            else
            {
                logger.Warn($"{gwControler.DeviceInfo.Name} PowerOn Error!");
            }
        }

        private async void buttonPowerOff_Click(object sender, RoutedEventArgs e)
        {
            await DisOutputCtrl();
        }

        private async Task DisOutputCtrl()
        {
            var result = await gwControler.DisablePowerOutAsync();

            if (result == true)
            {

                await Dispatcher.BeginInvoke(new Action(() =>
                {
                    buttonPowerOn.IsEnabled = true;
                    buttonPowerOff.IsEnabled = false;
                }));
                
                logger.Info($"{gwControler.DeviceInfo.Name} PowerOff Ok!");
            }
            else
            {
                logger.Warn($"{gwControler.DeviceInfo.Name} PowerOff Error!");
            }
        }

        private void buttonClearCnt_Click(object sender, RoutedEventArgs e)
        {
            PowerOnCnt = 0;
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            logger.Info($"All Power Cnt={PowerOnCnt}");
            gwControler?.Dispose();
        }

        private void StartTestTask_Click(object sender, RoutedEventArgs e)
        {
            cancellation = new CancellationTokenSource();
            Task.Factory.StartNew(RepeatTestTask, cancellation.Token);
        }

        private void StopTestTask_Click(object sender, RoutedEventArgs e)
        {
            cancellation.Cancel();
            
        }

        public async void RepeatTestTask()
        {
            logger.Info($"Start Repeat Test (PowerOff {DelaySecond}s: PowerOn {OutputSecond}s testCnt:{TestCount})");
            for (RunCount = 0; RunCount < TestCount; RunCount++)
            {
                await Task.Delay(DelaySecond * 1000);
                await OutputCtrl();
                await Task.Delay(OutputSecond * 1000);
                await DisOutputCtrl();
            }
            logger.Info("Start Repeat Test Complited");
        }
    }
}
